package com.ruoyi.ai.factory.impl;

import cn.hutool.core.lang.UUID;
import com.alibaba.dashscope.common.Role;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.ai.domain.vo.ChatCommonVo;
import com.ruoyi.ai.domain.vo.WxChatVo;
import com.ruoyi.ai.domain.vo.WxModelConfigVo;
import com.ruoyi.ai.enums.MfgEnum;
import com.ruoyi.ai.enums.SparkModelEnum;
import com.ruoyi.ai.factory.ModelChatTemplate;
import com.ruoyi.ai.ws.ChatWebSocketManager;
import com.ruoyi.common.exception.ServiceException;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

/**
 * Kimi模型实现
 */
@Slf4j
@Service
public class KimiModelChatService extends ModelChatTemplate {
    @Resource
    private ChatWebSocketManager chatWebSocketManager;

    private final OkHttpClient client;

    public KimiModelChatService() {
        super(MfgEnum.KIMI.getType());
        this.client = new OkHttpClient.Builder()
            .connectTimeout(60, TimeUnit.SECONDS)
            .writeTimeout(60, TimeUnit.SECONDS)
            .readTimeout(60, TimeUnit.SECONDS)
            .build();
    }

    @Override
    public String chatStream(List<WxChatVo> chatVoList, Long userId) {
        try {
            log.info("发送的请求为{}", chatVoList);
            // 同步信号量
            Semaphore semaphore = new Semaphore(0);
            // 结果拼接对象
            StringBuilder resultBuilder = new StringBuilder();

            WxModelConfigVo config = getConfig();
            String url =config.getUrl();
            if(config.getUrl() == null){
                SparkModelEnum sparkModelEnum = SparkModelEnum.getByType(config.getModelType());
                 url =sparkModelEnum.getHost();
            }

            // 构建请求体
            Map<String, Object> requestBody = new HashMap<>();
            requestBody.put("model", config.getModelType());
            List<Map<String, String>> messages = new ArrayList<>();
            for (WxChatVo chatVo : chatVoList) {
                Map<String, String> message = new HashMap<>();
                message.put("role", chatVo.getRole().equals("assistant")?"system":"user");
                if(ObjectUtils.isEmpty(chatVo.getContent())){
                    continue;
                }
                message.put("content", chatVo.getContent());
                messages.add(message);
            }
            requestBody.put("messages", messages);
            requestBody.put("stream", true);

            ObjectMapper mapper = new ObjectMapper();
            String jsonBody = mapper.writeValueAsString(requestBody);

            Request request = new Request.Builder()
                .url(url)
                .addHeader("Authorization", "Bearer " + config.getApiKey())
                .post(RequestBody.create(jsonBody, MediaType.parse("application/json")))
                .build();

            client.newCall(request).enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                    log.error("请求失败", e);
                    semaphore.release();
                }

                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    try (BufferedReader reader = new BufferedReader(
                        new InputStreamReader(response.body().byteStream()))) {
                        String line;
                        while ((line = reader.readLine()) != null) {
                            if (line.startsWith("data: ")) {
                                String jsonData = line.substring(6);
                                if ("[DONE]".equals(jsonData)) {
                                    continue;
                                }
                                JsonNode node = mapper.readTree(jsonData);
                                String content = node.path("choices").path(0).path("delta").path("content").asText();
                                if (!content.isEmpty()) {
                                    resultBuilder.append(content);
                                    chatWebSocketManager.sendOneMessage(userId, content);
                                }
                            }
                        }
                        log.info(userId+"请求相应", resultBuilder.toString());
                    } catch (Exception e) {
                        log.error("处理响应失败", e);
                    } finally {
                        semaphore.release();
                    }
                }
            });

            semaphore.acquire();
            chatWebSocketManager.sendOneMessage(userId, OVER_FLAG);
            return resultBuilder.toString();
        } catch (Exception e) {
            log.error("调用Kimi接口出现问题：{}", e.getMessage());
            throw new ServiceException("调用Kimi接口出现问题");
        }
    }

    @Override
    public String chatStreamOnce(String content, ChatCommonVo chatCommonVo) {
        try {
            log.info("发送的请求为{}", content);
            // 同步信号量
            Semaphore semaphore = new Semaphore(0);
            // 结果拼接对象
            StringBuilder resultBuilder = new StringBuilder();

            WxModelConfigVo config = getConfigByMfg(chatCommonVo.getModel());
            String url =config.getUrl();
            if(config.getUrl() == null){
                SparkModelEnum sparkModelEnum = SparkModelEnum.getByType(config.getModelType());
                 url =sparkModelEnum.getHost();
            }

            // 构建请求体
            Map<String, Object> requestBody = new HashMap<>();
            requestBody.put("model", config.getModelType());
            List<Map<String, String>> messages = new ArrayList<>();
            Map<String, String> message = new HashMap<>();
            message.put("role", Role.USER.getValue());
            message.put("content", content);
            messages.add(message);
            if(chatCommonVo!=null&&chatCommonVo.getSystemContent() != null){
                Map<String, String> sysmessage = new HashMap<>();
                sysmessage.put("role", Role.SYSTEM.getValue());
                message.put("content", chatCommonVo.getSystemContent());
                messages.add(message);
            }

            requestBody.put("messages", messages);
            requestBody.put("stream", true);

            ObjectMapper mapper = new ObjectMapper();
            String jsonBody = mapper.writeValueAsString(requestBody);

            Request request = new Request.Builder()
                .url(url)
                .addHeader("Authorization", "Bearer " + config.getApiKey())
                .post(RequestBody.create(jsonBody, MediaType.parse("application/json")))
                .build();

            client.newCall(request).enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                    log.error("请求失败", e);
                    semaphore.release();
                }

                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    try (BufferedReader reader = new BufferedReader(
                        new InputStreamReader(response.body().byteStream()))) {
                        String line;
                        while ((line = reader.readLine()) != null) {
                            if (line.startsWith("data: ")) {
                                String jsonData = line.substring(6);
                                if ("[DONE]".equals(jsonData)) {
                                    continue;
                                }
                                JsonNode node = mapper.readTree(jsonData);
                                String content = node.path("choices").path(0).path("delta").path("content").asText();
                                if (!content.isEmpty()) {
                                    resultBuilder.append(content);
                                }
                            }
                        }
                    } catch (Exception e) {
                        log.error("处理响应失败", e);
                    } finally {
                        semaphore.release();
                    }
                }
            });

            semaphore.acquire();
            return resultBuilder.toString();
        } catch (Exception e) {
            log.error("调用Kimi接口出现问题：{}", e.getMessage());
            return "调用大模型接口失败，请稍后尝试";
        }
    }
}
